---
title: Web only features
description: Learn about web only features in Unistyles 3.0
---

import { Aside } from '@astrojs/starlight/components'
import Seo from '../../../../components/Seo.astro'

<Seo
    seo={{
        title: 'Web only features',
        description: 'Learn about web only features in Unistyles 3.0'
    }}
>

Unistyles comes with some web-only features that are not available with React Native or React Native Web.

### Web only styles

In Unistyles, you can use web-specific styles for your web app under the `_web` key.

```ts
const styles = StyleSheet.create({
    container: {
        flex: 1,
        // Web only styles:
        _web: {
            display: 'grid',
        }
    }
})
```

Web styles support **any** CSS property and value that matches the `CSSProperties` type from React.

<Aside>
The `_web` styles are ignored on Android and iOS, but are merged with other styles on web.
</Aside>


Within `_web` block, you can't use any React Native specific styles:

```ts
const styles = StyleSheet.create({
    container: {
        flex: 1,
        _web: {
          display: 'grid',
          // 💥 Error! This is React Native specific style
          transform: [{ translateX: 10 }],
        }
    }
})
```

The `transform` property on the web should be a string:

```diff lang="ts"
const styles = StyleSheet.create({
    container: {
        flex: 1,
        _web: {
            display: 'grid',
-           transform: [{ translateX: 10 }],
+           transform: 'translateX(10px)',
        }
     }
})
```

If you want to use React Native specific styles on web simply move them to the `style` level:

```diff lang="ts"
const styles = StyleSheet.create({
    container: {
        flex: 1,
        // ✅ This is React Native specific style, and will be parsed correctly for web
+        transform: [{ translateX: 10 }],
        _web: {
            display: 'grid',
-           transform: [{ translateX: 10 }],
        }
    }
})
```

You can also use variants, breakpoints, and other Unistyles features under the `_web` key!

### Pseudo elements

Unistyles also introduces a way to use **any** pseudo-elements and selectors in your web styles.

```ts
const styles = StyleSheet.create(theme => ({
    button: {
        backgroundColor: theme.colors.button,
        _web: {
            _hover: {
                backgroundColor: theme.colors.hovered,
            },
            _before: {
                content: '"🦄"',
            }
        }
    },
}))
```

As you can see, `:` and `::` have been replaced with `_` for easier usage.

### Injecting custom classNames

If you want to write some part of your app with plain CSS, you can add custom `classNames` to your styles:

```ts
const styles = StyleSheet.create({
    container: {
        flex: 1,
        _web: {
            _classNames: 'my-custom-class',
        }
    }
})
```

The `_classNames` key under the `_web` key will be injected into the DOM element as a `className`. You can pass a string or an array of strings into it:

```diff lang="ts"
const styles = StyleSheet.create({
    container: {
        flex: 1,
        _web: {
-           _classNames: 'my-custom-class',
+           _classNames: ['my-custom-class', 'my-other-class'],
            // or _classNames: 'my-custom-class my-other-class'
        }
    }
})
```

You can also use some conditions while resolving your classes:

```ts
const styles = StyleSheet.create({
    button: (isPrimary: boolean) => ({
        _web: {
            _classNames: isPrimary ? 'primary-button' : 'secondary-button',
        }
    })
})
```

### CSS Variables

Unistyles 3.0 converts all your themes to CSS variables by default, eliminating heavy JS processing when changing the theme and allowing the CSS engine to take over.

In more detail, it converts all **strings** into CSS variables. For example, if we have the following theme:

```ts
const darkTheme = {
    colors: {
        primary: '#4b7594'
    },
    gap: (v: number) => v * 8,
    fontSize: 16
}
```

It will be converted to:

```css
:root.dark {
    --colors-primary: #4b7594;
}
```

After conversion, Unistyles will use CSS variable instead of string to reference the theme value.

##### If you're using `adaptiveThemes`
CSS variables will be placed under the `@media (prefers-color-scheme)` [query](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme) ensuring that the app will automatically switch to the new theme.

##### If you're not using `adaptiveThemes`
Class of your html root element will be updated to match the new one.

<Aside type="caution">
It's possible to [disable](/v3/start/configuration#settings-optional) this feature in some cases.
</Aside>

### When to disable CSS variables?

##### When you have different size variables / functions in your themes

```tsx
// ❌ Not OK
const regularTheme = {
    colors: sharedColors,
    gap: (v: number) => v * 8,
    fontSize: 16
}

const largeTheme = {
    colors: sharedColors,
    // gap function has a different factor
    gap: (v: number) => v * 16,
    // fontSize is a different value
    fontSize: 32
}
```

```tsx
// ✅ OK
const lightTheme = {
    colors: {
        ...sharedColors,
        background: '#fff',
        typography: '#000'
    },
    gap: (v: number) => v * 8,
    fontSize: 16
}

const darkTheme = {
    colors: {
        ...sharedColors,
        background: '#000',
        typography: '#fff'
    },
    gap: (v: number) => v * 8,
    fontSize: 16
}
```

##### When you use conditions to style your components instead of relying on the same theme values

```tsx
// ❌ Not OK
const styles = StyleSheet.create(theme => ({
    container: {
        // this is a condition and won't work with CSS variables
        backgroundColor: theme.isDark
            ? theme.colors.grey200
            : theme.colors.grey700
    }
}))
```

```tsx
// ✅ OK
const styles = StyleSheet.create(theme => ({
    container: {
        // your rely on the same theme values across different themes
        backgroundColor: theme.colors.background
    }
}))
```

If none of the above applies to you, you can use CSS variables to boost your app's performance.
</Seo>
